package main

import (
	"flag"
	"os"
	"fmt"
	"compressTools/util"
	"compressTools/tinify"
	"path/filepath"
	"time"
	"math/rand"
	"errors"
)

type support struct{
	format map[string]bool
}

const (
	NotFile = 1
)

var (
	key string
	dir string
	supportFormat support
)

func init() {
	flag.StringVar(&key, "s", "", "set tinify key")
	flag.StringVar(&dir, "d", "", "set save directory")

	// 设置支持格式
	supportFormat.format = map[string]bool{
		".jpg": true,
		".jpeg": true,
		".png": true,
		".gif": true,
	}
}

func main() {
	flag.Parse()

	var files []string
	if len(key) > 0 {
		files = os.Args[3:]
	} else {
		key = "w7QlS9Efzi6Vo1wBbWW3HN9EIuThJ04e"	// 默认key
		files = os.Args[1:]
	}

	if len(files) == 0 {
		fmt.Println("not files")
		os.Exit(NotFile)
	}

	tinify.SetKey(key)
	var done = make(chan int, len(files))

	for _, arg := range files {
		go func(arg string) {
			var file = string(arg)
			if err := check(&supportFormat, file); err != nil {
				fmt.Errorf("%s\n", err)
				done <- 1
				return
			}

			toFile, err := compressFile(file, "./")
			if err != nil {
				fmt.Errorf("%s\n", err)
				done <- 1
				return
			}

			fmt.Printf("original:%s target:%s\n", file, toFile)
			done <- 1
		}(arg)
	}

	for i := 0; i < cap(done); i++ {
		<- done
	}
}

func compressFile(file string, dir string) (string, error) {
	var ext = filepath.Ext(file)

	source, err := tinify.FormFile(file)
	if err != nil {
		return "", err
	}

	toFile, err := createToFile(dir, ext)
	if err != nil {
		return "", err
	}

	err = source.ToFile(toFile)
	if err != nil {
		return "", err
	}

	return toFile, nil
}

func check(sup *support, file string) error {
	var ext = filepath.Ext(file)

	if util.PathExists(file) == false {
		return errors.New(fmt.Sprintf("%s not directory\n", file))
	}

	if sup.checkFormat(ext) == false {
		return errors.New(fmt.Sprintf("%s Format unsupported\n", file))
	}

	return nil
}

func createToFile(dir string, ext string) (string, error) {
	absDir, err := filepath.Abs(dir)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%s/%s%s", absDir, randName(), ext), nil
}

func randName() string {
	now := time.Now()
	return fmt.Sprintf("%d%d%d%d%d%d%d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), rand.Intn(10000))
}

func (s *support) checkFormat(ext string) bool {
	return len(ext) > 0 && s.format[ext] == true
}